#ifndef SOUND_ALSASOUNDSYSTEM_H_
#define SOUND_ALSASOUNDSYSTEM_H_

#include "base/constructormagic.h"
#include "sound/alsasymboltable.h"
#include "sound/soundsysteminterface.h"

namespace cricket {

	class AlsaStream;
	class AlsaInputStream;
	class AlsaOutputStream;

	// Sound system implementation for ALSA, the predominant sound device API on
	// Linux (but typically not used directly by applications anymore).
	class AlsaSoundSystem : public SoundSystemInterface {
		friend class AlsaStream;
		friend class AlsaInputStream;
		friend class AlsaOutputStream;
	public:
		static SoundSystemInterface *Create() {
			return new AlsaSoundSystem();
		}

		AlsaSoundSystem();

		virtual ~AlsaSoundSystem();

		virtual bool Init();
		virtual void Terminate();

		virtual bool EnumeratePlaybackDevices(SoundDeviceLocatorList *devices);
		virtual bool EnumerateCaptureDevices(SoundDeviceLocatorList *devices);

		virtual bool GetDefaultPlaybackDevice(SoundDeviceLocator **device);
		virtual bool GetDefaultCaptureDevice(SoundDeviceLocator **device);

		virtual SoundOutputStreamInterface *OpenPlaybackDevice(
			const SoundDeviceLocator *device,
			const OpenParams &params);
		virtual SoundInputStreamInterface *OpenCaptureDevice(
			const SoundDeviceLocator *device,
			const OpenParams &params);

		virtual const char *GetName() const;

	private:
		bool IsInitialized() { return initialized_; }

		bool EnumerateDevices(SoundDeviceLocatorList *devices,
			bool capture_not_playback);

		bool GetDefaultDevice(SoundDeviceLocator **device);

		static size_t FrameSize(const OpenParams &params);

		template <typename StreamInterface>
		StreamInterface *OpenDevice(
			const SoundDeviceLocator *device,
			const OpenParams &params,
			snd_pcm_stream_t type,
			StreamInterface *(AlsaSoundSystem::*start_fn)(
			snd_pcm_t *handle,
			size_t frame_size,
			int wait_timeout_ms,
			int flags,
			int freq));

		SoundOutputStreamInterface *StartOutputStream(
			snd_pcm_t *handle,
			size_t frame_size,
			int wait_timeout_ms,
			int flags,
			int freq);

		SoundInputStreamInterface *StartInputStream(
			snd_pcm_t *handle,
			size_t frame_size,
			int wait_timeout_ms,
			int flags,
			int freq);

		const char *GetError(int err);

		bool initialized_;
		AlsaSymbolTable symbol_table_;

		DISALLOW_COPY_AND_ASSIGN(AlsaSoundSystem);
	};

}  // namespace cricket

#endif  // SOUND_ALSASOUNDSYSTEM_H_
